{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-01-08T10:57:13.795756Z",
     "start_time": "2025-01-08T10:57:13.556344Z"
    }
   },
   "source": [
    "# 导入库\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import random"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 数据连接",
   "id": "d5f92db89e89f040"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-08T11:05:01.309894Z",
     "start_time": "2025-01-08T11:05:01.299171Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 创建两个数据框\n",
    "df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],\n",
    "                        'data1': np.random.randint(0, 10, 7)})\n",
    "df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],\n",
    "                        'data2': np.random.randint(0, 10, 3)})\n",
    "\n",
    "#默认连接使用相同的列名，连接方式是内连接\n",
    "# 连接方式：inner，left，right，outer\n",
    "# 内连接：只保留两个数据框中都存在的行\n",
    "# 左连接：保留左边数据框的所有行，即使右边数据框没有对应的行\n",
    "# 右连接：保留右边数据框的所有行，即使左边数据框没有对应的行\n",
    "# 外连接：保留两个数据框的所有行，即使两边都没有对应的行\n",
    "\n",
    "# 连接方式：inner\n",
    "print(f'内连接：\\n{pd.merge(df_obj1, df_obj2)}')\n",
    "\n",
    "#左df和右df都拿索引连接\n",
    "# 连接方式：left\n",
    "print(f'左连接：\\n{pd.merge(df_obj1, df_obj2, how=\"left\")}')\n",
    "\n",
    "#右df和左df都拿索引连接\n",
    "# 连接方式：right\n",
    "print(f'右连接：\\n{pd.merge(df_obj1, df_obj2, how=\"right\")}')\n",
    "\n",
    "# 连接方式：outer\n",
    "print(f'外连接：\\n{pd.merge(df_obj1, df_obj2, how=\"outer\")}')\n"
   ],
   "id": "a3b74beb7317199b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "内连接：\n",
      "  key  data1  data2\n",
      "0   b      2      8\n",
      "1   b      8      8\n",
      "2   a      5      8\n",
      "3   a      9      8\n",
      "4   a      2      8\n",
      "5   b      3      8\n",
      "左连接：\n",
      "  key  data1  data2\n",
      "0   b      2    8.0\n",
      "1   b      8    8.0\n",
      "2   a      5    8.0\n",
      "3   c      6    NaN\n",
      "4   a      9    8.0\n",
      "5   a      2    8.0\n",
      "6   b      3    8.0\n",
      "右连接：\n",
      "  key  data1  data2\n",
      "0   a    5.0      8\n",
      "1   a    9.0      8\n",
      "2   a    2.0      8\n",
      "3   b    2.0      8\n",
      "4   b    8.0      8\n",
      "5   b    3.0      8\n",
      "6   d    NaN      9\n",
      "外连接：\n",
      "  key  data1  data2\n",
      "0   a    5.0    8.0\n",
      "1   a    9.0    8.0\n",
      "2   a    2.0    8.0\n",
      "3   b    2.0    8.0\n",
      "4   b    8.0    8.0\n",
      "5   b    3.0    8.0\n",
      "6   c    6.0    NaN\n",
      "7   d    NaN    9.0\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 索引连接",
   "id": "a5fd685cfc2e2a27"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-08T11:00:56.646064Z",
     "start_time": "2025-01-08T11:00:56.634971Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 索引连接\n",
    "\n",
    "# 连接方式：inner\n",
    "pd.merge(df_obj1, df_obj2, left_index=True, right_index=True)\n",
    "print(f'内连接：\\n{pd.merge(df_obj1, df_obj2, left_index=True, right_index=True)}')\n",
    "\n",
    "# 连接方式：left\n",
    "pd.merge(df_obj1, df_obj2, left_index=True, right_index=True, how=\"left\")\n",
    "print(f'左连接：\\n{pd.merge(df_obj1, df_obj2, left_index=True, right_index=True, how=\"left\")}')\n",
    "\n",
    "# 连接方式：right\n",
    "pd.merge(df_obj1, df_obj2, left_index=True, right_index=True, how=\"right\")\n",
    "print(f'右连接：\\n{pd.merge(df_obj1, df_obj2, left_index=True, right_index=True, how=\"right\")}')\n",
    "\n",
    "# 连接方式：outer\n",
    "pd.merge(df_obj1, df_obj2, left_index=True, right_index=True, how=\"outer\")\n",
    "print(f'外连接：\\n{pd.merge(df_obj1, df_obj2, left_index=True, right_index=True, how=\"outer\")}')"
   ],
   "id": "c7077c5dc073371c",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "内连接：\n",
      "  key_x  data1 key_y  data2\n",
      "0     b      8     a      1\n",
      "1     b      0     b      3\n",
      "2     a      4     d      9\n",
      "左连接：\n",
      "  key_x  data1 key_y  data2\n",
      "0     b      8     a    1.0\n",
      "1     b      0     b    3.0\n",
      "2     a      4     d    9.0\n",
      "3     c      0   NaN    NaN\n",
      "4     a      8   NaN    NaN\n",
      "5     a      5   NaN    NaN\n",
      "6     b      4   NaN    NaN\n",
      "右连接：\n",
      "  key_x  data1 key_y  data2\n",
      "0     b      8     a      1\n",
      "1     b      0     b      3\n",
      "2     a      4     d      9\n",
      "外连接：\n",
      "  key_x  data1 key_y  data2\n",
      "0     b      8     a    1.0\n",
      "1     b      0     b    3.0\n",
      "2     a      4     d    9.0\n",
      "3     c      0   NaN    NaN\n",
      "4     a      8   NaN    NaN\n",
      "5     a      5   NaN    NaN\n",
      "6     b      4   NaN    NaN\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-08T11:01:38.896933Z",
     "start_time": "2025-01-08T11:01:38.883918Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 列连接\n",
    "\n",
    "# 连接方式：inner\n",
    "pd.merge(df_obj1, df_obj2, left_on='key', right_on='key')\n",
    "print(f'内连接：\\n{pd.merge(df_obj1, df_obj2, left_on=\"key\", right_on=\"key\")}')\n",
    "\n",
    "# 连接方式：left\n",
    "pd.merge(df_obj1, df_obj2, left_on='key', right_on='key', how=\"left\")\n",
    "print(f'左连接：\\n{pd.merge(df_obj1, df_obj2, left_on=\"key\", right_on=\"key\", how=\"left\")}')\n",
    "\n",
    "# 连接方式：right\n",
    "pd.merge(df_obj1, df_obj2, left_on='key', right_on='key', how=\"right\")\n",
    "print(f'右连接：\\n{pd.merge(df_obj1, df_obj2, left_on=\"key\", right_on=\"key\", how=\"right\")}')\n",
    "\n",
    "# 连接方式：outer\n",
    "pd.merge(df_obj1, df_obj2, left_on='key', right_on='key', how=\"outer\")\n",
    "print(f'外连接：\\n{pd.merge(df_obj1, df_obj2, left_on=\"key\", right_on=\"key\", how=\"outer\")}')"
   ],
   "id": "a4dfab8339576394",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "内连接：\n",
      "  key  data1  data2\n",
      "0   b      8      3\n",
      "1   b      0      3\n",
      "2   a      4      1\n",
      "3   a      8      1\n",
      "4   a      5      1\n",
      "5   b      4      3\n",
      "左连接：\n",
      "  key  data1  data2\n",
      "0   b      8    3.0\n",
      "1   b      0    3.0\n",
      "2   a      4    1.0\n",
      "3   c      0    NaN\n",
      "4   a      8    1.0\n",
      "5   a      5    1.0\n",
      "6   b      4    3.0\n",
      "右连接：\n",
      "  key  data1  data2\n",
      "0   a    4.0      1\n",
      "1   a    8.0      1\n",
      "2   a    5.0      1\n",
      "3   b    8.0      3\n",
      "4   b    0.0      3\n",
      "5   b    4.0      3\n",
      "6   d    NaN      9\n",
      "外连接：\n",
      "  key  data1  data2\n",
      "0   a    4.0    1.0\n",
      "1   a    8.0    1.0\n",
      "2   a    5.0    1.0\n",
      "3   b    8.0    3.0\n",
      "4   b    0.0    3.0\n",
      "5   b    4.0    3.0\n",
      "6   c    0.0    NaN\n",
      "7   d    NaN    9.0\n"
     ]
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-08T11:05:56.359347Z",
     "start_time": "2025-01-08T11:05:56.353926Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 更改列名\n",
    "# .rename()方法可以更改列名, 但需要指定参数columns\n",
    "df_obj1 = df_obj1.rename(columns={'key': 'key1'})\n",
    "df_obj2 = df_obj2.rename(columns={'key': 'key2'})\n",
    "\n",
    "# 处理重复列名\n",
    "df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],\n",
    "                    'data': np.random.randint(0, 10, 7)})\n",
    "df2 = pd.DataFrame({'key': ['a', 'b', 'd'],\n",
    "                    'data': np.random.randint(0, 10, 3)})\n",
    "# 给相同的数据列添加后缀\n",
    "# suffixes参数可以指定后缀\n",
    "print(pd.merge(df1, df2, on='key', suffixes=('_left', '_right')))"
   ],
   "id": "defcf03772753566",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  key  data_left  data_right\n",
      "0   b          1           6\n",
      "1   b          5           6\n",
      "2   a          2           4\n",
      "3   a          2           4\n",
      "4   a          1           4\n",
      "5   b          5           6\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "#",
   "id": "7967ea0b20659d4f"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
